package com.yindian.cos.easy.security.authentication.login.social.core;

import com.yindian.cos.easy.security.properties.EasySecurityProperties;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.util.Date;
import java.util.List;

/**
 * 默认mysql存储第三方用户策略
 *
 * @author zhangchuanhao
 * @create 2018/11/20
 */
@Log4j2
public class MysqlUserInfoStore implements UserInfoStore {

    private final JdbcTemplate jdbcTemplate;

    private final static String tableSql = "CREATE TABLE %s (" +
            "`user_id` varchar(255) NOT NULL COMMENT '业务系统用户id', " +
            "`provider` varchar(255) NOT NULL COMMENT '提供方（qq、微信、新浪微博）', " +
            "`open_id` varchar(255) NOT NULL COMMENT '第三方平台id', " +
            "`nick_name` varchar(255) NOT NULL COMMENT '昵称', " +
            "`img_url` varchar(255) DEFAULT NULL COMMENT '用户头像', " +
            "`access_token` varchar(255) NOT NULL, " +
            "`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', " +
            "UNIQUE KEY `unique_idx` (`user_id`,`provider`) USING BTREE COMMENT '用户id，提供商组成用户唯一主键' " +
            ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;";

    private final static String column = " user_id userId," +
            " provider," +
            " open_id openId," +
            " nick_name nickName," +
            " img_url imgUrl," +
            " access_token accessToken," +
            " create_time createTime ";

    private static String tableName = "social_user";

    public MysqlUserInfoStore(DataSource dataSource, EasySecurityProperties easySecurityProperties) {
        jdbcTemplate = new JdbcTemplate(dataSource);
        String tablePrefix = easySecurityProperties.getTablePrefix();
        if (StringUtils.isNotBlank(tablePrefix)) {
            tableName = tablePrefix + tableName;
        }
        if (!tableExist(tableName)) {
            log.debug("easy security创建表：{}", tableName);
            jdbcTemplate.update(String.format(tableSql, tableName));
        }
    }

    public boolean tableExist(String tableName) {
        String sql = "SELECT COUNT(*) FROM " + tableName;
        try {
            jdbcTemplate.execute(sql);
            return true;
        } catch (BadSqlGrammarException e) {
            return false;
        }
    }

    @Override
    public boolean saveUserInfo(UserInfo userInfo) {
        String sql = "insert into " + tableName +
                " (user_id,provider,open_id,nick_name,img_url,access_token,create_time)" +
                " values (?,?,?,?,?,?,?)";

        jdbcTemplate.update(sql, new Object[]{
                userInfo.getUserId(),
                userInfo.getProvider(),
                userInfo.getOpenId(),
                userInfo.getNickName(),
                userInfo.getImgUrl(),
                userInfo.getAccessToken(),
                new Date()
        });
        log.debug("{}登录，保存用户信息到本地，userInfo = {}", userInfo.getProvider(), userInfo);
        return true;
    }

    @Override
    public UserInfo getUserInfo(String provider, String openId) {
        String sql = "select " + column +
                " from " + tableName +
                " where " +
                " provider = ?" +
                " and open_id = ? ";
        UserInfo userInfo = null;
        List<UserInfo> userInfoList = jdbcTemplate.query(sql, new Object[]{provider, openId}, new BeanPropertyRowMapper(UserInfo.class));
        if (!userInfoList.isEmpty()) {
            userInfo = userInfoList.get(0);
        }
        log.debug("{}登录，尝试从本地获取用户，openId = {},userInfo = {}", provider, openId, userInfo);
        return userInfo;
    }

    @Override
    public List<UserInfo> getUserInfoList(String userId) {
        String sql = "select " + column +
                " from " + tableName +
                " where " +
                " user_id = ?";

        List<UserInfo> userInfoList = jdbcTemplate.query(sql, new Object[]{userId}, new BeanPropertyRowMapper(UserInfo.class));
        log.debug("获取用户绑定的第三方登录列表，userInfoList = {}", userInfoList);
        return userInfoList;
    }

    @Override
    public boolean unBundle(String userId, String provider) {
        String sql = "delete from " + tableName + " where user_id = ? and provider = ?";
        jdbcTemplate.update(sql, new Object[]{userId, provider});
        log.debug("解除{}登录绑定，userId = {}", provider, userId);
        return true;
    }
}
